package com.dom.springcore;

import com.dom.exception.BeanClassMissingException;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;


import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

public class HandleBeansInfo {

    private HandleBeansInfo() {
    }

    /* beansInfoMaps是来存储配置文件中列出的所有创建对象的信息；
     * 每一个<bean>标签对应一个BeanInfo 对象
     */

    public static HashMap<String, BeanInfo> beansInfoMaps =
            new HashMap<String, BeanInfo>();

    /*
     * activebeansMaps是来存储容器已经创建好的对象，供外界调用；
     */
    public static HashMap<String, Object> activebeansMaps =
            new HashMap<String, Object>();

    static {
        try {
            // 1. 直接通过类加载器获取beans.xml的输入流（关键修改）
            // 路径说明："com/hugeyurt/springcore/beans.xml" 是相对于classpath根目录的路径
            InputStream is = HandleBeansInfo.class.getClassLoader()
                    .getResourceAsStream("beans.xml");

            // 2. 判空：防止资源不存在（比原来的FileNotFoundException更提前报错）
            if (is == null) {
                throw new FileNotFoundException("未找到beans.xml！请检查路径是否正确，资源是否在classpath下");
            }

            // 3. 用输入流构建Document（不再用File）
            SAXBuilder builder = new SAXBuilder();
            Document doc = builder.build(is);  // 关键：传入InputStream，而非File

            Element foo = doc.getRootElement();//得到根节点
            List<Element> children = foo.getChildren();

            for (int i = 0; i < children.size(); i++) {
                Element element = children.get(i);

                // 核心修改：判断class属性是否缺失，缺失则抛自定义异常
                if (element.getAttribute("class") == null) {
                    // 抛出异常，携带具体信息（如第几个Bean缺失，方便排查）
                    throw new BeanClassMissingException(
                            "XML配置中第" + (i + 1) + "个<bean>标签缺失必需的class属性，请检查beans.xml"
                    );
                }
                BeanInfo bean = new BeanInfo();
                bean.setClassName(element.getAttributeValue("class"));

                if (element.getAttribute("scope") != null)
                    bean.setScope(element.getAttributeValue("scope"));
                else bean.setScope("single");

                if (element.getAttribute("name") != null)
                    bean.setObjectName(element.getAttributeValue("name"));
                else if (element.getAttribute("id") != null)
                    bean.setObjectName(element.getAttributeValue("id"));
                else
                    bean.setObjectName(getObjectName(bean.getClassName()));

                List<Element> subChildern = element.getChildren();
                if (subChildern==null||subChildern.size()==0) {
                    beansInfoMaps.put(bean.getObjectName(),bean);
                    continue;
                }
                List<String> propertiesName=new ArrayList<String>();
                List<String> propertiesValue=new ArrayList<String>();
                for (int k = 0; k < subChildern.size(); k++) {
                    Element property = subChildern.get(k);
                    String name = property.getAttributeValue("name");
                    propertiesName.add(name);
                    String value = property.getAttributeValue("value");
                    if(value!=null) {
                        propertiesValue.add(value);
                    } else {
                        String ref = property.getAttributeValue("ref");
                        propertiesValue.add("ref:"+ref);
                    }
                }
                bean.setProperties(propertiesName);
                bean.setValues(propertiesValue);
                beansInfoMaps.put(bean.getObjectName(), bean);
            }
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        } catch (JDOMException ex) {
            throw new RuntimeException(ex);
        } catch (BeanClassMissingException e) {
            throw new RuntimeException(e);
        }


    }

    public static String  getObjectName(String className)
    {
        int index=className.lastIndexOf(".");
        char[] result=className.substring(index+1).toCharArray();
        if(result[0]<='Z'&&result[0]>='A')
            result[0]=(char)(result[0]+32);
        return new String(result);
    }


    public static void main(String[] args) {
        //String className="com.hugeyurt.hello";
        //  System.out.print(HandleBeansInfo.getObjectName(className));
        Set<String> keys=HandleBeansInfo.beansInfoMaps.keySet();
        for (String string : keys)
        {
            System.out.println(HandleBeansInfo.beansInfoMaps.get(string));
        }

    }


}
